import './style.scss';
import { download } from './assets';
import Message from './message';
import { render, updateNode, useState, useRef, classnames } from 'rjsx';
import { ROUTERMAP, STYLE_SUB_IDENTIFIER } from './constants';

function CreateVItem({ title, bvid, aid, cid, main_title, ep_id }: Record<string, any>) {
  const value = [encodeURIComponent(title), bvid, aid, cid, ep_id].join('::');
  const labelVal = [main_title, title].filter(Boolean).join('-');
  return (
    <div class="v-item">
      <input class="v-i-checkbox" type="checkbox" name="vinfoindex" id={cid} value={btoa(value)} />
      <label class="v-i-label" for={cid} title={labelVal}>{labelVal}</label>
    </div>
  );
}
const videoIsEmpty = useState(false);
function GetVNodes({ desc }: any) {
  const routerKey = Object.keys(ROUTERMAP).find(key => location.pathname.startsWith(ROUTERMAP[key])) || '?';
  try {
    let videoDatas: VDInfoType[] = [];
    if (routerKey === 'bangumi') {
      videoDatas = twoHandler(); // bangumi
    } else if (routerKey === 'cheese') {
      videoDatas = threeHandler(); // cheese
    } else if (routerKey === 'festival') {
      videoDatas = fourHandler(); // festival
    } else {
      videoDatas = oneHandler(); // video | list
    }

    if (desc) {
      videoDatas.reverse();
    }
    return videoDatas.map(item => <CreateVItem {...item} />);
  } catch (_) {
    videoIsEmpty.value = true;
    Message.error('获取视频信息失败');
    return [<div class="v-c-empty">~~暂无内容~~</div>];
  }
}

const oneHandler = () => {
  let videos: VDInfoType[] = [];
  const {
    bvid,
    aid,
    title,
    cid,
    ugc_season,
    pages
  } = __INITIAL_STATE__.videoData!; // 当前视频

  if (ugc_season) {
    videos = ugc_season.sections?.map(({
      title: main_title, episodes
    }) => episodes?.map(({ cid, title, bvid, aid }) => ({
      cid, title, bvid, aid, main_title
    }))).flat();
  } else if (pages) {
    videos = pages.map(({ cid, part: title }) => ({ cid, title, bvid, aid }));
  } else {
    videos.push({ cid, title, bvid, aid });
  }
  return videos;
}
const twoHandler = () => {
  const init_queries = __NEXT_DATA__.props.pageProps.dehydratedState.queries;
  return init_queries.map(({ state }) => state.
    data.seasonInfo.mediaInfo.episodes
    .map(({ bvid, aid, cid, playerEpTitle: title, ep_id }) => ({ aid, bvid, cid, title, ep_id }))).flat();
}
const threeHandler = () => {
  let videos: VDInfoType[] = [];
  return videos;
}
const fourHandler = () => {
  return __INITIAL_STATE__.sectionEpisodes!; // 当前视频合集
}

let isMounted = true;

const wrapDom = useRef();
const clearHandler = () => {
  wrapDom.current?.remove();
  isMounted = true;
}
const VideoList = () => {
  const sortState = useState(false);
  const formDom = useRef<HTMLFormElement>();
  const sortedAction = () => {
    if (videoIsEmpty.value) {
      return;
    }
    updateNode(formDom.current, <GetVNodes desc={sortState.value = !sortState.value} />);
  }

  const downloadAction = () => {
    if (videoIsEmpty.value) {
      return;
    }
    const formData = new FormData(formDom.current);
    const vinfoVals = formData.getAll('vinfoindex');
    const vinfos: VInfoType[] = vinfoVals.map(item => {
      const [title, bvid, aid, cid, ep_id] = atob(item.toString()).split('::');
      return {
        title: decodeURIComponent(title),
        bvid,
        aid: Number(aid),
        cid: Number(cid),
        ep_id,
      }
    });
    if (!vinfos.length) {
      return Message.warning('请选择后再操作');
    }
    download(vinfos);
  }
  return (
    <div ref={wrapDom} class="v-download-wrap" role="table">
      <div class="v-head">
        <span>可选视频列表</span>
        <div class="v-h-a-wrap">
          <span class='v-h-action sort' title='排序' onClick={sortedAction} />
          <span class='v-h-action download' title='下载' onClick={downloadAction} />
          <span class='v-h-action close' title='关闭' onClick={clearHandler} />
        </div>
      </div>
      <form ref={formDom} class="v-content"><GetVNodes /></form>
    </div>
  )
};

const clickHandler = () => {
  if (isMounted) {
    isMounted = false;
    render(<VideoList />, document.body);
  }
}

const App = ({ cclass }: any) => (
  <span title="批量下载" class={classnames('batch-btn', 'video-toolbar-left-item', cclass)} onClick={clickHandler}>
    <svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" style="margin-right:8px;" class="video-toolbar-item-icon">
      <path fill="currentColor" d="M12 2C6.49 2 2 6.49 2 12s4.49 10 10 10s10-4.49 10-10S17.51 2 12 2zm-1 8V7c0-.55.45-1 1-1s1 .45 1 1v3h1.79c.45 0 .67.54.35.85l-2.79 2.79c-.2.2-.51.2-.71 0l-2.79-2.79a.5.5 0 0 1 .36-.85H11zm5 7H8c-.55 0-1-.45-1-1s.45-1 1-1h8c.55 0 1 .45 1 1s-.45 1-1 1z" />
    </svg>
    <span>下载</span>
  </span>
);

//#region 初始化
let app: HTMLElement | null;
if (import.meta.env.DEV) {
  app = document.getElementById('app');
  // import('./data/index.json').then(data => window.__INITIAL_STATE__ = data);
  import('./data/festival.json').then(data => window.__INITIAL_STATE__ = data);
  render(<App />, app!);
} else {
  let cclass = '';
  app = document.querySelector('.video-toolbar-left, .toolbar');
  if (!app) {
    app = document.querySelector('.video-toolbar-content_left');
    cclass = 'festival';
  }

  render(<style type="text/css">{STYLE_SUB_IDENTIFIER}</style>, document.head);
  isMounted = true;
  const appObserver = new MutationObserver((
    _mutations: MutationRecord[],
    observer: MutationObserver
  ) => {
    render(<App cclass={cclass} />, app!);
    observer.disconnect();
    observerVideo();
  });
  app && appObserver.observe(app, {
    childList: true,
    attributes: true,
    attributeOldValue: true,
    characterData: true,
    characterDataOldValue: true,
    subtree: true
  });
}

function observerVideo() {
  const player = document.querySelector('#bilibili-player video');
  const playerObserver = new MutationObserver(() => {
    console.log("refresh...");
    clearHandler();
  });
  player && playerObserver.observe(player, {
    attributes: true
  });
}
//#endregion 初始化